from typing import List, Dict, Any, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, Path, Body
from sqlalchemy.ext.asyncio import AsyncSession
from app.cache.decorators import cached

from app.database import get_db
from app.schemas.schemas import (
    ResponseBase, SchoolListResponse, SchoolResponse, ClassFiltersResponse, 
    ClassListResponse, ClassCoursesResponse, ClassResponse, ClassCoursesRequest
)
from app.crud import crud_school, crud_class, crud_course

# 创建API路由
router = APIRouter(prefix="/api/v1")

@router.get("/schools", response_model=SchoolListResponse)
@cached(ttl=3600, key_prefix="schools")
async def get_schools(db: AsyncSession = Depends(get_db)):
    """
    获取所有学校
    """
    schools_from_db = await crud_school.get_schools(db)
    # 手动将SQLAlchemy模型列表转换为Pydantic模型列表
    schools_response = [SchoolResponse.model_validate(s) for s in schools_from_db]
    return {
        "code": 200,
        "data": schools_response,
        "message": "success"
    }

@router.get("/classes/filters", response_model=ClassFiltersResponse)
@cached(ttl=300, key_prefix="class_filters")
async def get_class_filters(
    school_id: int = Query(..., description="学校ID"),
    academic_year: Optional[str] = Query(None, description="学年名称"),
    term: Optional[str] = Query(None, description="学期代码"),
    campus: Optional[str] = Query(None, description="校区名称"),
    college: Optional[str] = Query(None, description="学院名称"),
    grade: Optional[str] = Query(None, description="年级名称"),
    major: Optional[str] = Query(None, description="专业名称"),
    education_level: Optional[str] = Query(None, description="培养层次"),
    # 兼容前端复数参数（数组）形式：如 terms、majors 等
    academic_years: Optional[List[str]] = Query(None, description="学年(数组)别名"),
    terms: Optional[List[str]] = Query(None, description="学期(数组)别名"),
    campuses: Optional[List[str]] = Query(None, description="校区(数组)别名"),
    colleges: Optional[List[str]] = Query(None, description="学院(数组)别名"),
    grades: Optional[List[str]] = Query(None, description="年级(数组)别名"),
    majors: Optional[List[str]] = Query(None, description="专业(数组)别名"),
    education_levels: Optional[List[str]] = Query(None, description="培养层次(数组)别名"),
    db: AsyncSession = Depends(get_db)
):
    """
    获取班级筛选条件（支持动态联动筛选）
    
    根据已选的筛选条件，返回其他维度的可选值及对应的班级数量。
    不传入的参数认为用户未选中。
    
    示例：
    - 初始加载：GET /api/v1/classes/filters?school_id=1
    - 选中专业：GET /api/v1/classes/filters?school_id=1&major=软件工程
    - 多维度：GET /api/v1/classes/filters?school_id=1&major=软件工程&campus=东山校区
    """
    # 将复数(数组)参数兼容为单值（取第一个），保证后端筛选生效
    ay = academic_year or (academic_years[0] if academic_years else None)
    tm = term or (terms[0] if terms else None)
    cp = campus or (campuses[0] if campuses else None)
    clg = college or (colleges[0] if colleges else None)
    gd = grade or (grades[0] if grades else None)
    mj = major or (majors[0] if majors else None)
    el = education_level or (education_levels[0] if education_levels else None)

    filters = await crud_class.get_dynamic_class_filters(
        db, school_id, ay, tm, cp, clg, gd, mj, el
    )
    return {
        "code": 200,
        "data": filters,
        "message": "success"
    }

@router.get("/classes", response_model=ClassListResponse)
@cached(ttl=300, key_prefix="classes")
async def get_classes(
    school_id: int = Query(..., description="学校ID"),
    academic_year: Optional[str] = Query(None, description="学年名称"),
    term: Optional[str] = Query(None, description="学期代码"),
    campus: Optional[str] = Query(None, description="校区名称"),
    college: Optional[str] = Query(None, description="学院名称"),
    grade: Optional[str] = Query(None, description="年级名称"),
    major: Optional[str] = Query(None, description="专业名称"),
    education_level: Optional[str] = Query(None, description="培养层次"),
    page: int = Query(1, ge=1, description="页码"),
    size: int = Query(10, ge=1, le=100, description="每页数量"),
    db: AsyncSession = Depends(get_db)
):
    """
    获取班级列表
    """
    classes, total = await crud_class.get_classes(
        db, school_id, academic_year, term, campus, college, 
        grade, major, education_level, page, size
    )
    
    # 手动将SQLAlchemy模型列表转换为Pydantic模型列表
    classes_response = [ClassResponse.model_validate(c) for c in classes]
    
    return {
        "code": 200,
        "data": {
            "list": classes_response,
            "total": total
        },
        "message": "success"
    }

@router.post("/classes/courses", response_model=ClassCoursesResponse)
@cached(ttl=300, key_prefix="class_courses")
async def get_class_courses(
    request: ClassCoursesRequest = Body(..., description="请求参数"),
    db: AsyncSession = Depends(get_db)
):
    """
    获取班级课程表
    
    请求体参数：
    - class_code: 班级编号（必填）
    - school_id: 学校ID（可选，用于提高查询稳定性）
    
    示例：
    ```json
    {
      "class_code": "23371101",
      "school_id": 1
    }
    ```
    """
    result = await crud_course.get_class_courses(
        db, 
        request.class_code, 
        school_id=request.school_id
    )
    
    if not result:
        raise HTTPException(status_code=404, detail="班级不存在")
    
    return {
        "code": 200,
        "data": result,
        "message": "success"
    }
